require_dependency "search" 
require 'digest/sha1'
class User < ActiveRecord::Base  
  # Virtual attribute for the unencrypted password
  attr_accessor :password

  validates_presence_of     :login,                 :email
  validates_presence_of     :password,              :if => :password_required?
  validates_presence_of     :password_confirmation, :if => :password_required?
  validates_length_of       :password,              :within => 4..40,           :if => :password_required?
  validates_confirmation_of :password,              :if => :password_required?
  validates_length_of       :login,                 :within => 3..40
  validates_length_of       :email,                 :within => 3..100
  validates_uniqueness_of   :login,                 :email,                     :case_sensitive => false
  before_save               :encrypt_password
  
  has_many                  :galleries,             :through => :partnerships
  has_many                  :comments
  has_many                  :partnerships
  has_many                  :orders
  has_many                  :items
  has_many                  :approvals
  searches_on :login,
              :email,
              :first_name,
              :last_name,
              :street_address,
              :city,
              :state
              
  has_friendly_id           :login, :use_slug => true
  
  after_save                :create_partnerships
  after_destroy             :destroy_dependents
  
  def has_in_cart?(item)
    has_in_cart = false
    (self.orders.each {|order| (has_in_cart = true) if order.photos.include?(item)} unless self.orders.empty?) if item.is_a?(Photo)
    (self.orders.each {|order| (has_in_cart = true) if order.videos.include?(item)} unless self.orders.empty?) if item.is_a?(Video)
    has_in_cart
  end
  
  def authorized_to_view?(item)
    if item.is_private?
      #case item.class.to_s
      #  when "Photo"
      #    (item.users.include?(self) or self.is_admin?) ? (return true) : (return false)
      #  when "Video"
      #    (item.users.include?(self) or self.is_admin?) ? (return true) : (return false)
      #  when "Gallery"
      #    (item.users.include?(self) or self.is_admin? or item.public?) ? (return true) : (return false)
      #  when "Page"
      #    (item.users.include?(self) or self.is_admin? or item.public?) ? (return true) : (return false)
      #end
      ((item.users.include?(self) or self.is_admin?) ? (return true) : (return false)) if item.is_a?(Photo)
      ((item.users.include?(self) or self.is_admin?) ? (return true) : (return false)) if item.is_a?(Video)
      ((item.users.include?(self) or self.is_admin? or item.public?) ? (return true) : (return false)) if item.is_a?(Gallery)
      ((item.users.include?(self) or self.is_admin? or item.public?) ? (return true) : (return false)) if item.is_a?(Page)
    end
    true
  end
  
  # prevents a user from submitting a crafted form that bypasses activation
  # anything else you want your user to change should be added here.
  attr_accessible :login, :email, :password, :password_confirmation, :first_name, :last_name, :street_address, :city, :state, :zip, :phone_number, :is_admin, :is_client, :gallery_ids

  # Authenticates a user by their login name and unencrypted password.  Returns the user or nil.
  def self.authenticate(login, password)
    u = find_by_login(login) # need to get the salt
    u && u.authenticated?(password) ? u : nil
  end

  # Encrypts some data with the salt.
  def self.encrypt(password, salt)
    Digest::SHA1.hexdigest("--#{salt}--#{password}--")
  end

  # Encrypts the password with the user salt
  def encrypt(password)
    self.class.encrypt(password, salt)
  end

  def authenticated?(password)
    crypted_password == encrypt(password)
  end

  def remember_token?
    remember_token_expires_at && Time.now.utc < remember_token_expires_at 
  end

  # These create and unset the fields required for remembering users between browser closes
  def remember_me
    remember_me_for 2.weeks
  end

  def remember_me_for(time)
    remember_me_until time.from_now.utc
  end

  def remember_me_until(time)
    self.remember_token_expires_at = time
    self.remember_token            = encrypt("#{email}--#{remember_token_expires_at}")
    save(false)
  end

  def forget_me
    self.remember_token_expires_at = nil
    self.remember_token            = nil
    save(false)
  end

  # Returns true if the user has just been activated.
  def recently_activated?
    @activated
  end

  def gallery_ids=(gallery_ids = [])
    @gallery_ids = gallery_ids
  end

protected
  def create_partnerships
    (self.partnerships.each {|partnership| partnership.destroy if partnership.gallery and @gallery_ids}) if self.partnerships
    @gallery_ids.each {|gallery_id| Partnership.create!(:user_id => self.id, :gallery_id => gallery_id)} unless @gallery_ids.nil?
  end

  def destroy_dependents
    self.comments.each {|comment| comment.destroy} unless self.comments.empty?
    self.partnerships.each {|partnership| partnership.destroy} unless self.partnerships.empty?
    self.approvals.each {|approval| approval.destroy} unless self.approvals.empty?
    self.orders.each {|order| order.destroy} unless self.orders.empty?
    self.items.each {|item| item.destroy} unless self.items.empty?
  end

  # before filter 
  def encrypt_password
    return if password.blank?
    self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record?
    self.crypted_password = encrypt(password)
  end
    
  def password_required?
    crypted_password.blank? || !password.blank?
  end
end
